package cn.itcast.wanxinp2p.consumer.service.impl;


import cn.itcast.wanxinp2p.api.account.model.account.AccountDTO;
import cn.itcast.wanxinp2p.api.account.model.account.AccountRegisterDTO;
import cn.itcast.wanxinp2p.api.account.model.comsumer.ConsumerDTO;
import cn.itcast.wanxinp2p.api.account.model.comsumer.ConsumerRegisterDTO;
import cn.itcast.wanxinp2p.api.consumer.model.BankCardDTO;
import cn.itcast.wanxinp2p.api.consumer.model.ConsumerRequest;
import cn.itcast.wanxinp2p.api.depository.model.DepositoryConsumerResponse;
import cn.itcast.wanxinp2p.api.depository.model.GatewayRequest;
import cn.itcast.wanxinp2p.common.domain.CodePrefixCode;
import cn.itcast.wanxinp2p.common.domain.ConsumerErrorCode;
import cn.itcast.wanxinp2p.common.domain.DepositoryReturnCode;
import cn.itcast.wanxinp2p.common.domain.RestResponse;
import cn.itcast.wanxinp2p.common.domain.StatusCode;
import cn.itcast.wanxinp2p.common.exception.BusinessException;
import cn.itcast.wanxinp2p.common.util.CodeNoUtil;
import cn.itcast.wanxinp2p.consumer.agent.AccountApiAgent;
import cn.itcast.wanxinp2p.consumer.agent.DepositoryAgentApiAgent;
import cn.itcast.wanxinp2p.consumer.domain.BankCard;
import cn.itcast.wanxinp2p.consumer.domain.Consumer;
import cn.itcast.wanxinp2p.consumer.mapper.ConsumerMapper;
import cn.itcast.wanxinp2p.consumer.service.BankCardService;
import cn.itcast.wanxinp2p.consumer.service.ConsumerService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hmily.annotation.Hmily;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.baomidou.mybatisplus.core.toolkit.Wrappers.query;
import static com.baomidou.mybatisplus.core.toolkit.Wrappers.update;


@Slf4j
@Service
public class ConsumerServiceImpl implements ConsumerService {

    @Autowired
    ConsumerMapper consumerMapper;

    @Autowired
    BankCardService bankCardService;

    @Autowired
    private AccountApiAgent accountApiAgent;

    @Autowired
    private DepositoryAgentApiAgent depositoryAgentApiAgent;

    @Override
    public Integer checkMobile(String mobile) {
        //根据手机号查询用户，存在返回1 不存在返回0
        Consumer consumer = consumerMapper.selectByMobile(mobile);
        if (consumer != null) {
            return 1;
        }
        return 0;
    }

    @Override
    @Hmily(confirmMethod = "confirmRegister", cancelMethod = "cancelRegister")
    public void register(ConsumerRegisterDTO consumerRegisterDTO) {
        //1、检测是否已注册，如果已经注册，则抛出 ConsumerErrorCode.E_140107 异常
        Consumer consumer = consumerMapper.selectByMobile(consumerRegisterDTO.getMobile());
        //2、如果用户没有注册，则保存该用户数据 到 consumer 表中
        if (consumer != null) {
            throw new BusinessException(ConsumerErrorCode.E_140107);
        }
        consumer = new Consumer();
        BeanUtils.copyProperties(consumerRegisterDTO, consumer);
        consumer.setUsername(CodeNoUtil.getNo(CodePrefixCode.CODE_NO_PREFIX));
        consumer.setUserNo(CodeNoUtil.getNo(CodePrefixCode.CODE_CONSUMER_PREFIX));
        consumer.setIsBindCard(0);
        consumerMapper.register(consumer);
        //3、并通过Feign远程调用 统一账号服务 实现 账号的保存
        AccountRegisterDTO accountRegisterDTO = new AccountRegisterDTO();
        BeanUtils.copyProperties(consumerRegisterDTO, accountRegisterDTO);
        RestResponse<AccountDTO> restResponse = accountApiAgent.register(accountRegisterDTO);
        if (restResponse.getResult() == null) {
            throw new BusinessException(ConsumerErrorCode.E_140106);
        }
    }

    public void confirmRegister(ConsumerRegisterDTO consumerRegisterDTO) {
        //用户已存在修改状态为1
        consumerMapper.updateByStatus(StatusCode.STATUS_OUT.getCode(), consumerRegisterDTO.getMobile());
        log.info("-------------- 执行 confirmRegister");
    }

    public void cancelRegister(ConsumerRegisterDTO consumerRegisterDTO) {
        log.info("-------------- 执行 cancelRegister");
        //TODO 删除用户
        Consumer consumer = consumerMapper.selectByMobile(consumerRegisterDTO.getMobile());
        if (consumer == null) {
            return;
        }
        if (StatusCode.STATUS_OUT.getCode() != consumer.getStatus()) {
            consumerMapper.deleteByMobile(consumerRegisterDTO.getMobile());
        }
    }


    @Override
    @Transactional
    public RestResponse<GatewayRequest> createConsumer(ConsumerRequest consumerRequest) {
        //根据手机号查询用户信息
        Consumer consumer = consumerMapper.selectByMobile(consumerRequest.getMobile());
        //判断用户是否已开户 IS_BIND_CARD
        if (consumer != null && 1 == consumer.getIsBindCard()) {
            throw new BusinessException(ConsumerErrorCode.E_140105);
        }

        //判断银行卡是否已被绑定  STATUS=1 表示已绑定，已绑定的银行卡，不能在进行操作，抛出 ConsumerErrorCode.E_140151 异常
        BankCardDTO bankCardDTO1 = bankCardService.getByCardNumber(consumerRequest.getCardNumber());
        if (bankCardDTO1 != null && bankCardDTO1.getStatus() == StatusCode.STATUS_IN.getCode()) {
            throw new BusinessException(ConsumerErrorCode.E_140151);
        }
        // 给consumerRequest对象 设置用户开户id  consumerDTO.getId()
        // 给consumerRequest对象 产生请求流水号： CodeNoUtil.getNo(CodePrefixCode.CODE_CONSUMER_PREFIX)
        //                        和用户编号：  CodeNoUtil.getNo(CodePrefixCode.CODE_REQUEST_PREFIX)
        consumerRequest.setId(consumer.getId());
        consumerRequest.setRequestNo(CodeNoUtil.getNo(CodePrefixCode.CODE_REQUEST_PREFIX));
        consumerRequest.setUserNo(CodeNoUtil.getNo(CodePrefixCode.CODE_CONSUMER_PREFIX));
        //更新 consumer用户数据
        /*
           update  consumer set user_no =?,request_no=?,full_name=?,id_number=?,authlist='ALL'
           where mobile = ?
         */
        BeanUtils.copyProperties(consumerRequest, consumer);
//        consumer.setStatus(StatusCode.STATUS_IN.getCode());
//        consumer.setIsBindCard(StatusCode.STATUS_IN.getCode());
        consumerMapper.update(consumer);

        //保存或者跟新用户绑卡信息 bank_card表
        //  主要有如下信息：用户id，银行编码，银行编码，银行预留手机号，可用状态默认设置为 0
        // 根据用户id查询，如果存在则是更新，否则是新增
        BankCardDTO bankCardDTO = bankCardService.getByConsumerId(consumer.getId());

        BankCard bankCard = new BankCard();
        BeanUtils.copyProperties(consumerRequest, bankCard);
        bankCard.setConsumerId(consumer.getId());
        bankCard.setStatus(StatusCode.STATUS_OUT.getCode());
        if (bankCardDTO != null) {
            bankCard.setId(bankCardDTO.getId());
            bankCardService.updateBankCard(bankCard);
        }else {
            bankCardService.saveBankCard(bankCard);
        }


        //通过Feign接口，调用银行存管代理服务，并返回调用的结果
        return depositoryAgentApiAgent.createConsumer(consumerRequest);
    }

    @Override
    public ConsumerDTO getConsumer(String mobile) {
        Consumer consumer = consumerMapper.selectByMobile(mobile);
        ConsumerDTO consumerDTO = new ConsumerDTO();
        if (consumer != null) {
            BeanUtils.copyProperties(consumer, consumerDTO);
        }
        return consumerDTO;
    }


    @Override
    @Transactional
    public Boolean modifyResult(DepositoryConsumerResponse response) {
        //1.获取状态
        int status = DepositoryReturnCode.RETURN_CODE_00000.getCode().equals(response.getRespCode()) ? StatusCode.STATUS_IN.getCode():StatusCode.STATUS_FAIL.getCode();
        //2.更新开户结果
        Consumer consumer = getByRequestNo(response.getRequestNo());
        update(Wrappers.<Consumer>lambdaUpdate().eq(Consumer::getId,consumer.getId()).set(Consumer::getIsBindCard, status).set(Consumer::getStatus,status));
        //3.更新银行卡信息
        return bankCardService.update(Wrappers.<BankCard>lambdaUpdate().eq(BankCard::getConsumerId, consumer.getId()).set(BankCard::getStatus, status).set(BankCard::getBankCode,response.getBankCode())
                .set(BankCard::getBankName, response.getBankName()));
    }

    private Consumer getByRequestNo(String requestNo){
        return consumerMapper.selectByRequestNo(requestNo);
 }


}